/*
复制数组
*/
const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;



/*
合并数组
*/
const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];
// ES5 的合并数组
arr1.concat(arr2, arr3);
// [ 'a', 'b', 'c', 'd', 'e' ]
// ES6 的合并数组
[...arr1, ...arr2, ...arr3]
// [ 'a', 'b', 'c', 'd', 'e' ]

//不过，这两种方法都是浅拷贝，使用的时候需要注意。
const a1 = [{
	foo: 1
}];
const a2 = [{
	bar: 2
}];
const a3 = a1.concat(a2);
const a4 = [...a1, ...a2];
a3[0] === a1[0] // true
a4[0] === a1[0] // true



/*
解构赋值结合
*/
[a, ...rest] = list

const [first, ...rest] = [1, 2, 3, 4, 5];
first // 1
rest // [2, 3, 4, 5]

const [first, ...rest] = [];
first // undefined
rest // []

const [first, ...rest] = ["foo"];
first // "foo"
rest // []

//...一定要在最后一位
const [...butLast, last] = [1, 2, 3, 4, 5];
// 报错
const [first, ...middle, last] = [1, 2, 3, 4, 5];
// 报错



/*
字符串转数组
*/
[...'hello'] // [ "h", "e", "l", "l", "o" ]



/*
任何定义了遍历器（Iterator）接口的对象（参阅 Iterator 一章），都可以用扩展运算符转为真正的数组。
*/

let nodeList = document.querySelectorAll('div'); //定义了遍历器（Iterator)
let array = [...nodeList]; //dom集合转数组


Number.prototype[Symbol.iterator] = function*() {
	let i = 0;
	let num = this.valueOf();
	while (i < num) {
		yield i++;
	}
}
console.log([...5]) // [0, 1, 2, 3, 4]


/*
Map 和 Set 结构，Generator 函数
扩展运算符内部调用的是数据结构的 Iterator 接口
因此只要具有 Iterator 接口的对象，都可以使用扩展运算符
*/
// Map 结构。
let map = new Map([
	[1, 'one'],
	[2, 'two'],
	[3, 'three'],
]);
let arr = [...map.keys()]; // [1, 2, 3]

//Generator 函数
const go = function*() {
	yield 1;
	yield 2;
	yield 3;
};
[...go()] // [1, 2, 3]

